/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    usart.c
  * @brief   This file provides code for the configuration
  *          of the USART instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usart.h"

/* USER CODE BEGIN 0 */
#define RXBUFFERSIZE  256  

char RxBuffer[RXBUFFERSIZE]; 
uint8_t aRxBuffer;			  
uint8_t Uart1_Rx_Cnt = 0;  

SEND_DATA Send_Data;
RECEIVE_DATA Receive_Data;
/* USER CODE END 0 */

UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart1_tx;

/* USART1 init function */

void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}
/* USART2 init function */

void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspInit 0 */

  /* USER CODE END USART1_MspInit 0 */
    /* USART1 clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART1 GPIO Configuration
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* USART1 DMA Init */
    /* USART1_RX Init */
    hdma_usart1_rx.Instance = DMA1_Channel5;
    hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart1_rx.Init.Mode = DMA_NORMAL;
    hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);

    /* USART1_TX Init */
    hdma_usart1_tx.Instance = DMA1_Channel4;
    hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart1_tx.Init.Mode = DMA_NORMAL;
    hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx);

    /* USART1 interrupt Init */
    HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);
  /* USER CODE BEGIN USART1_MspInit 1 */

  /* USER CODE END USART1_MspInit 1 */
  }
  else if(uartHandle->Instance==USART2)
  {
  /* USER CODE BEGIN USART2_MspInit 0 */

  /* USER CODE END USART2_MspInit 0 */
    /* USART2 clock enable */
    __HAL_RCC_USART2_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART2 GPIO Configuration
    PA2     ------> USART2_TX
    PA3     ------> USART2_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* USART2 interrupt Init */
    HAL_NVIC_SetPriority(USART2_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);
  /* USER CODE BEGIN USART2_MspInit 1 */

  /* USER CODE END USART2_MspInit 1 */
  }
}

void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{

  if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspDeInit 0 */

  /* USER CODE END USART1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_USART1_CLK_DISABLE();

    /**USART1 GPIO Configuration
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);

    /* USART1 DMA DeInit */
    HAL_DMA_DeInit(uartHandle->hdmarx);
    HAL_DMA_DeInit(uartHandle->hdmatx);

    /* USART1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USART1_IRQn);
  /* USER CODE BEGIN USART1_MspDeInit 1 */

  /* USER CODE END USART1_MspDeInit 1 */
  }
  else if(uartHandle->Instance==USART2)
  {
  /* USER CODE BEGIN USART2_MspDeInit 0 */

  /* USER CODE END USART2_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_USART2_CLK_DISABLE();

    /**USART2 GPIO Configuration
    PA2     ------> USART2_TX
    PA3     ------> USART2_RX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);

    /* USART2 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USART2_IRQn);
  /* USER CODE BEGIN USART2_MspDeInit 1 */

  /* USER CODE END USART2_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */


void usart2_data_transition(void)
{
	Send_Data.buffer[0]=FRAME_HEADER; //Frame_heade //??
	
	Send_Data.buffer[1]=Start_flag; //Car software loss marker

	Send_Data.buffer[2]=environment_temp>>8;
	Send_Data.buffer[3]=environment_temp;
	Send_Data.buffer[4]=environment_hum>>8;
	Send_Data.buffer[5]=environment_hum;
	Send_Data.buffer[6]=VoltageValue[0]>>8;
	Send_Data.buffer[7]=VoltageValue[0];
	
	Send_Data.buffer[8]=0;
	Send_Data.buffer[9]=0;
	Send_Data.buffer[10]=0;
	Send_Data.buffer[11]=0;
	Send_Data.buffer[12]=0;
	Send_Data.buffer[13]=0;
	Send_Data.buffer[14]=0;
	Send_Data.buffer[15]=0;
	Send_Data.buffer[16]=0;
	Send_Data.buffer[17]=0;
	Send_Data.buffer[18]=0;
	Send_Data.buffer[19]=0;
	Send_Data.buffer[20]=0;
	Send_Data.buffer[21]=0;


	Send_Data.buffer[22]=Check_Sum(22,1); 
	
	Send_Data.buffer[23]=FRAME_TAIL; //Frame_tail //?��
	
	USART2_SEND();
	
	//According to different vehicle types, different kinematics algorithms were selected to carry
}
/**************************************************************************
Function: Serial port 1 sends data
Input   : none
Output  : none
?????????????1????????
??????????
????  ?????
**************************************************************************/
void USART1_SEND(void)
{
  unsigned char i = 0;	
	
	for(i=0; i<24; i++)
	{
		usart1_send(Send_Data.buffer[i]);
	}	 
}
void USART2_SEND(void)
{
  unsigned char i = 0;	
	
	for(i=0; i<24; i++)
	{
		usart2_send(Send_Data.buffer[i]);
	}	 
}

/**************************************************************************
Function: After the top 8 and low 8 figures are integrated into a short type data, the unit reduction is converted
Input   : 8 bits high, 8 bits low
Output  : The target velocity of the robot on the X/Y/Z axis
**************************************************************************/
float XYZ_Target_Speed_transition(uint8_t High,uint8_t Low)
{
	//Data conversion intermediate variable
	short transition; 
	
	//The high 8 and low 8 bits are integrated into a 16-bit short data
	transition=((High<<8)+Low); 
	return 
		transition/1000+(transition%1000)*0.001; //Unit conversion, mm/s->m/s 			
}
/**************************************************************************
Function: Serial port 1 sends data
Input   : The data to send
Output  : none
?????????????1????????
??????????????????
????  ?????
**************************************************************************/
/**
 * @brief  ???USART1???????????????
 * @param  data: ?????????????
 * @retval ??
 */
void usart1_send(uint8_t data)
{
    // ??????��??USART1???????????????????
    USART1->DR = data;
    // ??????????????????????????
    while((USART1->SR&0x40)==0);  
}
void usart2_send(uint8_t data)
{
    // ??????��??USART1???????????????????
    USART2->DR = data;
    // ??????????????????????????
    while((USART2->SR&0x40)==0);  
}
/**************************************************************************
Function: Calculates the check bits of data to be sent/received
Input   : Count_Number: The first few digits of a check; Mode: 0-Verify the received data, 1-Validate the sent data
Output  : Check result
??????????????????/?????????��????
????????Count_Number??��??????��????Mode??0-????????????��?�1-????????????��??
????  ???��????
**************************************************************************/
uint8_t Check_Sum(unsigned char Count_Number,unsigned char Mode)
{
	unsigned char check_sum=0,k;
	
	//Validate the data to be sent
	//???????????????��??
	if(Mode==1)
	for(k=0;k<Count_Number;k++)
	{
	check_sum=check_sum^Send_Data.buffer[k];
	}
	
	//Verify the data received
	//???????????????��??
	if(Mode==0)
	for(k=0;k<Count_Number;k++)
	{
	check_sum=check_sum^Receive_Data.buffer[k];
	}
	return check_sum;
}
	
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_UART_TxCpltCallback could be implemented in the user file
   */
	
#ifdef enableESP32
	static u8 Count=0;
	Receive_Data.buffer[Count]=aRxBuffer;
	// Ensure that the first data in the array is FRAME_HEADER
	if(aRxBuffer == FRAME_HEADER||Count>0) 
		Count++; 
	else 
		Count=0;
	
	if (Count == 11) //Verify the length of the packet
	{   
		Count=0; //Prepare for the serial port data to be refill into the array
		if(Receive_Data.buffer[10] == FRAME_TAIL) //Verify the frame tail of the packet
		{
			//Data exclusionary or bit check calculation, mode 0 is sent data check
			if(Receive_Data.buffer[9] ==Check_Sum(9,0))	 
			{		
				X_Speed=-Receive_Data.buffer[3];
				if(Receive_Data.buffer[2] == 255)
				{
					X_Speed=Receive_Data.buffer[3];
				}
				
				Y_Speed=Receive_Data.buffer[5];
				if(Receive_Data.buffer[4] == 255)
				{
					Y_Speed=-Receive_Data.buffer[5];
				}
				
				Z_Speed=Receive_Data.buffer[7];  
				if(Receive_Data.buffer[6] == 255)
				{
					Z_Speed=-Receive_Data.buffer[7];  
				}
			}
		}
	}
	
	HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);  
#endif
	
#ifdef enableLD14	
	static const u8 CrcTable[256] =
	{
	0x00, 0x4d, 0x9a, 0xd7, 0x79, 0x34, 0xe3,
	0xae, 0xf2, 0xbf, 0x68, 0x25, 0x8b, 0xc6, 0x11, 0x5c, 0xa9, 0xe4, 0x33,
	0x7e, 0xd0, 0x9d, 0x4a, 0x07, 0x5b, 0x16, 0xc1, 0x8c, 0x22, 0x6f, 0xb8,
	0xf5, 0x1f, 0x52, 0x85, 0xc8, 0x66, 0x2b, 0xfc, 0xb1, 0xed, 0xa0, 0x77,
	0x3a, 0x94, 0xd9, 0x0e, 0x43, 0xb6, 0xfb, 0x2c, 0x61, 0xcf, 0x82, 0x55,
	0x18, 0x44, 0x09, 0xde, 0x93, 0x3d, 0x70, 0xa7, 0xea, 0x3e, 0x73, 0xa4,
	0xe9, 0x47, 0x0a, 0xdd, 0x90, 0xcc, 0x81, 0x56, 0x1b, 0xb5, 0xf8, 0x2f,
	0x62, 0x97, 0xda, 0x0d, 0x40, 0xee, 0xa3, 0x74, 0x39, 0x65, 0x28, 0xff,
	0xb2, 0x1c, 0x51, 0x86, 0xcb, 0x21, 0x6c, 0xbb, 0xf6, 0x58, 0x15, 0xc2,
	0x8f, 0xd3, 0x9e, 0x49, 0x04, 0xaa, 0xe7, 0x30, 0x7d, 0x88, 0xc5, 0x12,
	0x5f, 0xf1, 0xbc, 0x6b, 0x26, 0x7a, 0x37, 0xe0, 0xad, 0x03, 0x4e, 0x99,
	0xd4, 0x7c, 0x31, 0xe6, 0xab, 0x05, 0x48, 0x9f, 0xd2, 0x8e, 0xc3, 0x14,
	0x59, 0xf7, 0xba, 0x6d, 0x20, 0xd5, 0x98, 0x4f, 0x02, 0xac, 0xe1, 0x36,
	0x7b, 0x27, 0x6a, 0xbd, 0xf0, 0x5e, 0x13, 0xc4, 0x89, 0x63, 0x2e, 0xf9,
	0xb4, 0x1a, 0x57, 0x80, 0xcd, 0x91, 0xdc, 0x0b, 0x46, 0xe8, 0xa5, 0x72,
	0x3f, 0xca, 0x87, 0x50, 0x1d, 0xb3, 0xfe, 0x29, 0x64, 0x38, 0x75, 0xa2,
	0xef, 0x41, 0x0c, 0xdb, 0x96, 0x42, 0x0f, 0xd8, 0x95, 0x3b, 0x76, 0xa1,
	0xec, 0xb0, 0xfd, 0x2a, 0x67, 0xc9, 0x84, 0x53, 0x1e, 0xeb, 0xa6, 0x71,
	0x3c, 0x92, 0xdf, 0x08, 0x45, 0x19, 0x54, 0x83, 0xce, 0x60, 0x2d, 0xfa,
	0xb7, 0x5d, 0x10, 0xc7, 0x8a, 0x24, 0x69, 0xbe, 0xf3, 0xaf, 0xe2, 0x35,
	0x78, 0xd6, 0x9b, 0x4c, 0x01, 0xf4, 0xb9, 0x6e, 0x23, 0x8d, 0xc0, 0x17,
	0x5a, 0x06, 0x4b, 0x9c, 0xd1, 0x7f, 0x32, 0xe5, 0xa8
	};//????crc��???????
	
	if(huart == &huart2)
	{
		static u8 state = 0;//??��	??????????????��??
	  static u8 crc = 0;	//��???
	  static u8 cnt = 0;	//??????12????????
	  u8 temp_data; 
		temp_data=Usart2_Receive_buf[0]; 
			if (state > 5)	
			{
				if(state < 42)
				{
					if(state%3 == 0)		//???????��?????6,9.....39??????????????8��
					{
						Pack_Data.point[cnt].distance = (u16)temp_data;
						state++;
						crc = CrcTable[(crc^temp_data) & 0xff];
					}
					else if(state%3 == 1)	//???????��?????7,10.....40??????????????8��
					{
						Pack_Data.point[cnt].distance = ((u16)temp_data<<8)+Pack_Data.point[cnt].distance;
						state++;
						crc = CrcTable[(crc^temp_data) & 0xff];
					}
					else					//???????��?????8,11.....41????????????
					{
						Pack_Data.point[cnt].confidence = temp_data;
						cnt++;	
						state++;
						crc = CrcTable[(crc^temp_data) & 0xff];
					}
				}
				else 
				{
					switch(state)
					{
						case 42:
							Pack_Data.end_angle = (u16)temp_data;						//????????8��
							state++;
							crc = CrcTable[(crc^temp_data) & 0xff];
							break;
						case 43:
							Pack_Data.end_angle = ((u16)temp_data<<8)+Pack_Data.end_angle;//????????8��
							state++;
							crc = CrcTable[(crc^temp_data) & 0xff];
							break;
						case 44:
							Pack_Data.timestamp = (u16)temp_data;						//??????8��
							state++;
							crc = CrcTable[(crc^temp_data) & 0xff];
							break;
						case 45:
							Pack_Data.timestamp = ((u16)temp_data<<8)+Pack_Data.timestamp;//??????8��
							state++;
							crc = CrcTable[(crc^temp_data) & 0xff];
							break;
						case 46:
							Pack_Data.crc8 = temp_data;		//???????��???
							if(Pack_Data.crc8 == crc)		//��?????
							{
								data_process();				//?????????��???????????????????
							}
							else
							{
								memset(&Pack_Data, 0, sizeof(LiDARFrameTypeDef));//????
							}
							crc = 0;
							state = 0;
							cnt = 0;//??��
							break;
						default: break;
					}
				}
			}
			else 
			{
				switch(state)
				{
					case 0:
						if(temp_data == HEADER)									//????
						{
							Pack_Data.header = temp_data;
							state++;
							crc = CrcTable[(crc^temp_data) & 0xff];				//???????��??
						} else state = 0,crc = 0;
						break;
					case 1:
						if(temp_data == LENGTH)									//????????????????
						{
							Pack_Data.ver_len = temp_data;
							state++;
							crc = CrcTable[(crc^temp_data) & 0xff];
						} else state = 0,crc = 0;
						break;
					case 2:
						Pack_Data.speed = (u16)temp_data;						//????????8��????��?????
						state++;
						crc = CrcTable[(crc^temp_data) & 0xff];
						break;
					case 3:
						Pack_Data.speed = ((u16)temp_data<<8)+Pack_Data.speed;	//????????8��
						state++;
						crc = CrcTable[(crc^temp_data) & 0xff];
						break;
					case 4:
						Pack_Data.start_angle = (u16)temp_data;					//???????8��???????100??
						state++;
						crc = CrcTable[(crc^temp_data) & 0xff];
						break;
					case 5:
						Pack_Data.start_angle = ((u16)temp_data<<8)+Pack_Data.start_angle;
						state++;
						crc = CrcTable[(crc^temp_data) & 0xff];
						break;
					default: break;
				}
			}
	HAL_UART_Receive_IT(&huart2,Usart2_Receive_buf,sizeof(Usart2_Receive_buf));//????5?????????????????????��????????��???????��????��?????	
	}
#endif
}
/* USER CODE END 1 */
